<?php

namespace app\admin\controller;

use app\admin\model\ManagerLoginModel;
use app\common\service\EncryptService;
use extcore\traits\Upload;
use think\Controller;
use think\Db;
use think\Exception;

/**
 * 后台基类
 * 自带基于方法名的权限验证
 * Class BaseController
 * @package app\admin\controller
 */
class BaseController extends Controller {

    use Upload;

    protected $errMsg;
    protected $table;
    protected $model;

    protected $mid;
    protected $manager;
    protected $permision;

    protected $viewData=[];
    
    /**
     * 后台控制器全局初始化
     * @param $needLogin
     * @throws Exception
     */
    public function initialize(){
        parent::initialize();
        
        if(!defined('SUPER_ADMIN_ID'))define('SUPER_ADMIN_ID',config('super_admin_id'));
        if(!defined('TEST_ACCOUNT'))define('TEST_ACCOUNT',config('test_account'));

        $this->mid = session(SESSKEY_ADMIN_ID);
    

        $controller=strtolower($this->request->controller());
        if($controller === 'login'){
            return;
        }
        //未登录的自动登录
        if(empty($this->mid)){
            $this->autoLogin();
        }
        //判断用户是否登陆
        if(empty($this->mid ) ) {
            $this->error(lang('Please login first!'),url('admin/login/index'));
        }
        if(empty($this->manager)){
            $this->manager=Db::name('Manager')->where('id',$this->mid)->find();
        }
        if(empty($this->manager)){
            clearLogin();
            $this->error(lang('Invalid account!'),url('admin/login/index'));
        }
        if(TEST_ACCOUNT != $this->manager['username'] && $this->manager['logintime']!=session(SESSKEY_ADMIN_LAST_TIME)){
            clearLogin();
            $this->error(lang('The account has login in other places!'),url('admin/login/index'));
        }

        //$controller=strtolower($this->request->controller());
        if($controller!='index'){
            $action=strtolower($this->request->action());
            if($action != 'search') {
                if ($this->request->isPost() || $action == 'add' || $action == 'update') {
                    $this->checkPermision("edit");
                }
                if (strpos('del', $action) !== false || strpos('clear', $action) !== false) {
                    $this->checkPermision("del");
                }

                $this->checkPermision($controller . '_' . $action);
            }
        }

        if(!$this->request->isAjax()) {
            $this->assign('menus', getMenus());

            //空数据默认样式
            $this->assign('empty', list_empty());
        }
    }

    protected function autoLogin(){
        $loginsession = $this->request->cookie(SESSKEY_ADMIN_AUTO_LOGIN);
        if(!empty($loginsession)){
            cookie(SESSKEY_ADMIN_AUTO_LOGIN, null);
            $data = EncryptService::getInstance()->decrypt($loginsession);
            if(!empty($data)){
                $json = json_decode($data, true);
                if(!empty($json['hash'])){
                    $login = ManagerLoginModel::where('hash',$json['hash'])->find();
                    if(!empty($login)){
                        $timestamp = $json['time'];
                        if($timestamp >= time()){
                            $this->mid = $login['manager_id'];
                            $this->manager = Db::name('Manager')->where('id',$this->mid)->find();
                            setLogin($this->manager, 0);
                            $this->manager['logintime'] = session(SESSKEY_ADMIN_LAST_TIME);
                            $this->setAutoLogin($this->manager, $login['id']);
                        }
                    }
                }
            }
        }
    }

    protected function setAutoLogin($manager, $login_id = 0,$days = 7){
        $expire = $days * 24 * 60 * 60;
        $timestamp = time() + $expire;
        $hash = ManagerLoginModel::createHash($manager['id']);
        $data = EncryptService::getInstance()->encrypt(json_encode(['hash'=>$hash,'time'=>$timestamp]));
        cookie(SESSKEY_ADMIN_AUTO_LOGIN, $data, $expire);
        $data = [
            'hash'=>$hash,
            'update_time'=>time(),
            'login_time'=>time(),
            'login_ip'=>$this->request->ip(),
            'login_user_agent'=>$this->request->server('user_agent'),
        ];
        if($login_id > 0){
            ManagerLoginModel::where('id',$login_id)->update($data);
        }else{
            $data['manager_id']=$manager['id'];
            $data['create_time']=$data['update_time'];
            $data['device']=$this->parseDevice($data['login_user_agent']);
            $data['create_ip']=$data['login_ip'];
            $data['create_user_agent']=$data['login_user_agent'];
            ManagerLoginModel::create($data);
        }
    }

    private function parseDevice($userAgent){
        
        return $this->request->isMobile()?'mobile':'pc';
    }
    
    public function _empty(){
        
        $this->error('页面不存在',url('admin/index/index'));
    }

    /**
     * 检查权限
     * @param $permitem
     * @throws Exception
     */
    protected function checkPermision($permitem){
        if(!$this->getPermision($permitem)){
            $this->error(lang('You have no permission to do this operation!'));
        }
    }

    /**
     * 检查是否有权限
     * @param $permitem
     * @return bool
     * @throws Exception
     */
    protected function getPermision($permitem)
    {
        if($this->manager['type']==1){
            return true;
        }
        if(empty($this->permision)){
            $this->permision=Db::name('ManagerPermision')->where('manager_id',$this->mid)->find();
            if(empty($this->permision)){
                $this->error(lang('Bad permission settings, pls contact the manager!'));
            }
            $this->permision['global']=explode(',',$this->permision['global']);
            $this->permision['detail']=explode(',',$this->permision['detail']);
        }
        if(strpos($permitem,'_')>0){
            if(in_array($permitem,$this->permision['detail']))return true;
        }else{
            if(in_array($permitem,$this->permision['global']))return true;
        }
        return false;
    }
    
    protected function setAutoIncrement($table, $incre){
        $incre = intval($incre);
        if($incre<1){
            $this->error('起始id必须大于1');
        }
        $maxid = Db::name($table)->max('id');
        if($incre<$maxid){
            $this->error('起始id必须大于当前数据的最大id :'.$maxid);
        }
    
        try {
            Db::execute('ALTER TABLE ' . config('database.prefix').$table . ' AUTO_INCREMENT = ' . intval($incre));
        }catch(Exception $e){
            $this->error($e->getMessage());
        }
        
        user_log($this->mid,'set_increment',1,'设置['.$table.']起始id'.$incre,'manager');
        $this->success('设置成功');
    }

    /**
     * 兼容ajax的数据注册
     * @param mixed $name
     * @param string $value
     * @return $this
     */
    protected function assign($name, $value = '')
    {
        if($this->request->isAjax()) {
            if (is_array($name)) {
                $this->viewData = array_merge($this->viewData, $name);
            } else {
                $this->viewData[$name] = $value;
            }
        }else{
            $this->view->assign($name, $value);
        }

        return $this;
    }

    /**
     * 兼容ajax的输出
     * @param string $template
     * @param array $vars
     * @param array $config
     * @return string
     * @throws \Throwable
     */
    protected function fetch($template = '', $vars = [], $config = [])
    {
        if($this->request->isAjax()){
            $this->result($this->viewData,1);
        }

        return $this->view->fetch($template, $vars, $config);
    }

}